#pragma once

#include "media_stream.h"
#include <mutex>
#include <set>
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <memory>
#include <map>
#include <thread>

namespace El {
namespace StreamServer {

class StreamGstRtsp {
    DISALLOW_COPY_AND_MOVE(StreamGstRtsp);

public:
    struct MediaData {
        StreamGstRtsp *server; // 指向服务器实例的指针
        int32_t channel;
        int32_t stream_type;
        Media::StreamSourcePtr streamSource;
        int32_t stream_handle;
        GstElement *appsrc_video;
        GstElement *appsrc_audio;
    };
    using MediaDataPtr = std::shared_ptr<MediaData>;

    static StreamGstRtsp &GetInstance();

    StreamGstRtsp();

    ~StreamGstRtsp();

    bool Start();

    void Stop();

private:
    static void OnNewMedia(GstRTSPMediaFactory *factory, GstRTSPMedia *media, gpointer user_data);
    static void OnClientConnected(GstRTSPServer *server, GstRTSPClient *client, gpointer user_data);
    static void OnClientDisconnected(GstRTSPClient *client, gpointer user_data);
    void PushFrame(const Media::MediaFramePtr &frame, MediaDataPtr stream);

private:
    GMainLoop *loop_;
    GstRTSPServer *server_;
    std::thread main_loop_thread_;
    std::map<int, MediaDataPtr> media_data_;
    std::mutex media_data_mutex_;
    bool audio_enable_{false};
    std::set<GstRTSPClient *> clients_;
    std::mutex clients_mutex_;
};

} // namespace StreamServer
} // namespace El